package com.mybatis.lo.builder;

import com.mybatis.lo.config.Configuration;
import com.mybatis.lo.io.ClassPathResources;
import com.mybatis.lo.utils.DocumentUtils;
import org.apache.commons.dbcp.BasicDataSource;
import org.dom4j.Document;
import org.dom4j.Element;

import java.io.InputStream;
import java.util.List;
import java.util.Properties;

/**
 * 解析全局配置的构建器
 * @author zhangbh
 * 2023-06-16 07:31
 **/
public class XMLConfigurationBuilder extends BaseBuilder {

    public XMLConfigurationBuilder(Configuration configuration) {
        super(configuration);
    }

    public void loadConfiguration(Element element) {
        // 加载环境
        loadEnvironments(element);
        // 加载mappers映射配置文件
        loadMappers(element);
    }

    private void loadMappers(Element rootElement) {
        Element mappers = rootElement.element("mappers");
        List<Element> mapperList = mappers.elements("mapper");
        for (Element mapperElement : mapperList) {
            loadMapper(mapperElement);
        }
    }

    private void loadMapper(Element mapper) {
        String resource = mapper.attributeValue("resource");
        InputStream inputStream = new ClassPathResources().getResourceAsStream(resource);
        Document document = DocumentUtils.createDocument(inputStream);
        // 加载XXXMapper.xml
        XMLMapperBuilder mapperBuilder = new XMLMapperBuilder(configuration);
        mapperBuilder.loadMapper(document.getRootElement());
    }

    private void loadEnvironments(Element rootElement) {
        Element environments = rootElement.element("environments");
        String configDefault = environments.attributeValue("default");
        if (isNullOrEmpty(configDefault)) {
            System.out.println("指定数据库为空，直接退出");
            return;
        }
        loadDefaultEnvironment(environments, configDefault);
    }

    /**
     * 加载默认环境
     * @param environments 所有环境
     * @param configDefault 默认环境
     */
    private void loadDefaultEnvironment(Element environments, String configDefault) {
        List<Element> environment = environments.elements("environment");
        for (Element element : environment) {
            String id = element.attributeValue("id");
            if (isNullOrEmpty(id) || !configDefault.equals(id)) {
                continue;
            }
            loadDataSource(element.element("datasource"));
        }
    }

    /**
     * 处理 <datasource>
     * @param datasource 数据源标签
     */
    private void loadDataSource(Element datasource) {
        String dbType = datasource.attributeValue("type");
        if ("DBCP".equals(dbType)) {
            BasicDataSource dataSource = new BasicDataSource();
            Properties properties = loadProperties(datasource);
            dataSource.setDriverClassName(properties.getProperty("driverClassName"));
            dataSource.setUrl(properties.getProperty("url"));
            dataSource.setUsername(properties.getProperty("username"));
            dataSource.setPassword(properties.getProperty("password"));
            configuration.setDataSource(dataSource);
        } else {
            // todo 可补充其他数据源支持
            System.out.println("暂不支持的数据源");
        }
    }

    /**
     * 解析datasource.property标签
     * @param datasource 数据库配置标签
     * @return 配置属性
     */
    private Properties loadProperties(Element datasource) {
        Properties properties = new Properties();
        List<Element> propertys = datasource.elements("property");
        for (Element property : propertys) {
            String name = property.attributeValue("name");
            String value = property.attributeValue("value");
            properties.setProperty(name, value);
        }
        return properties;
    }

}
